home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Megahits 5
/
Megahits 5 (1994)(GTI - Rhein-Main-Soft)(DE)(Disc 2 of 2)[!].iso
/
archive
/
print
/
dvi2pcl.lha
/
dospecial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-25
|
14KB
|
463 lines
/* $Log: dospecial.c,v $
* Revision 0.8 92/11/23 19:46:42 19:46:42 bt (Bo Thide')
* Fixed resolution bug. Portable downloading. Added/changed options. PJXL color support
*
* Revision 0.7 92/11/13 02:41:26 02:41:26 bt (Bo Thide')
* More bug fixes and improvements. Support for PaintJet XL
*
* Revision 0.6 92/11/10 21:47:42 21:47:42 bt (Bo Thide')
* Bug fixes. Added -R option. Better font handling.
*
* Revision 0.5 92/11/09 16:25:29 16:25:29 bt (Bo Thide')
* Rewrite of dospecial.c. Extended \special support
*
* Revision 0.4 92/11/08 02:45:45 02:45:45 bt (Bo Thide')
* Changed to portable bit manipulations. Replaced strrstr for non-POSIX compliant C. Fixed numerous bugs. Added support for more \special's.
*
* Revision 0.3 92/08/24 12:45:37 12:45:37 bt (Bo Thide')
* Fixed 8 bit (dc font) support.
*
* Revision 0.2 92/08/23 17:28:56 17:28:56 bt (Bo Thide')
* Source cleaned up. Changed certain function calls. Removed globals.
*
* Revision 0.1 92/08/22 23:58:47 23:58:47 bt (Bo Thide')
* First Release.
* */
/*
* This procedure will handle any special commands that might appear.
* The following variants are handled:
*
* \special{command}
* \special{command(parameters)}
* \special{command=parameters}
* \special{command parameters}
* \special{command:parameters}
*
* The string contained in the special command is in the name array starting at
* 'nextnamesfree' and ending with a '\0'. Also, the 'prescan' boolean should
* be checked to see if this is the first or second time that this string was
* encountered.
*
* Copyright 1992 Bo Thide', Uppsala, Sweden <bt@irfu.se>.
*/
#define S_LANDSCAPE 0 /* Original \special "landscape" */
#define S_INCLUDE 1 /* Original \special "include()" */
#define S_GRAFIX 2 /* Original \special "grafix()" */
#define S_MOVE 3 /* Original \special "move()" */
#define S_ESCAPESEQ 4 /* dvi \special "escapeseq ..." */
#define S_RASTERFILE 5 /* dvi \special "rasterfile ..." */
#define S_RAWSTRING 6 /* dvi \special "rawstring ..." */
#define S_ORIENTATION 7 /* Gustaf Neumann's \special "orientation" */
#define S_FILE 8 /* Gustaf Neumann's \special "file" */
#define S_PS 9 /* PostScript \special's "ps:" */
#define S_EM 10 /* 'emtex' \special's "em:" */
#define S_PCL 11 /* PCL \special's "pcl:" */
#define S_HPGL 12 /* PCL5 \special's "hpgl:" */
#define S_PJXL 13 /* PaintJet XL \special "rawstring ..." */
#define SPECIALS 14 /* Number of \special's supported */
#define GRAFLIST 7 /* Number of graphics resolutions supported */
#define COLORLIST 8 /* Number of PaintJet XL text colors */
#include <ctype.h>
#include <stdio.h>
#include "globals.h"
#include "pcl.h"
static char rcsid[] = "$Header: dospecial.c,v 0.8 92/11/23 19:46:42 bt Exp $";
void dospecial(bitfile, prescan, pcllevel, hh, vv, resolution)
FILE *bitfile;
bool prescan;
short pcllevel;
long hh, vv;
short resolution;
{
/* The \special arguemnt keywords and their assocated delimiters */
static char *spclargv[SPECIALS][2] = {
"landscape", "",
"include", "(",
"grafix", "(",
"move", "(",
"escapeseq", " ",
"rasterfile", " ",
"rawstring", " ",
"orientation", "=",
"file", "=",
"ps", ":",
"em", ":",
"pcl", ":",
"hpgl", ":",
"pjxl", ":"
};
static char *graflist[] = {"600","300","180","150","100","90","75"};
static char *colorlist[] = {"black","red","green","yellow","blue",
"magenta","cyan","white"};
char *bufptr;
char *delimptr; /* Pointer to the argument delimiter */
char *iptr, *jptr; /* Generic pointers */
char c;
char drawrow[8];
char curname[NAMELENGTH]; /* Current name of generic file */
bool relative;
short angle=0;
short planes=1;
int i, j, k, l;
int pxl_rows, row_bytes;
int gflag;
int ic;
long hoffset, voffset;
FILE *genfile; /* Generic file pointer */
bufptr = nextnamesfree;
#ifdef DEBUG
fprintf(stderr,"\ndospecial: nextnamesfree = '%s'\n", nextnamesfree);
fprintf(stderr,"dospecial: prescan = '%d'\n", prescan);
fprintf(stderr,"dospecial: pcllevel = '%d'\n", pcllevel);
#endif /* DEBUG */
/* Process as long as the 'nextnamesfree' is not empty */
while(*bufptr){
while(isspace(*bufptr)) /* Skip over all leading white space */
bufptr++;
if(*bufptr){ /* Process only if it was not all white space */
iptr = jptr = bufptr;
while(isalpha(*jptr)) /* Move to the end of the first alpha string */
jptr++;
/* See if the first alpha string is an OK keyword */
k = 0;
while(strncmp(bufptr,spclargv[k][0],strlen(spclargv[k][0])))
k++; /* If the keyword is correct k points to it */
/* Locate the correct delimiter associated with the keyword */
while(*jptr && (*jptr != *spclargv[k][1]))
jptr++;
delimptr = jptr;
/*
* Bail out if no correct keyword (k >= SPECIALS)
* or no correct delimiter (*jptr == NULL) was found
*/
if(prescan && ((k >= SPECIALS) || !*jptr)) {
fprintf(stderr,"\ndospecial: \\special command not understood: %s\n",
nextnamesfree);
return;
}
/*
* Here we know that the keyword is OK and that delimptr points to
* the correct delimiter associated with that keyword.
*/
#ifdef DEBUG
fprintf(stderr,"\ndospecial: delimptr = '%s'\n", delimptr);
#endif /* DEBUG */
/* Move bufptr to point to the delimiter, after the first alpha string */
bufptr = delimptr;
/* Make sure the delimiter '(' has a matching ')' */
if(*delimptr == '(') {
bufptr++;
while((*bufptr != ')') && *bufptr)
bufptr++;
if(*bufptr == '\0')
fprintf(stderr,"\ndospecial: Expected ) after parameter in \\special{%s}.\n", nextnamesfree);
else
bufptr++;
}
else { /* Handle the other delimiters */
bufptr++;
while(*bufptr)
bufptr++;
}
/* Now bufptr points to the end of the nextnamesfree string */
/* Move jptr to point to after the (one byte) delimiter */
jptr = delimptr + 1;
/* Parse the rest of the string for keyword entry spclargv[k][0] */
switch (k) {
case S_LANDSCAPE: /* Landscape mode */
if(prescan)
landscape = TRUE;
break;
case S_INCLUDE: /* include(filename) */
if(!prescan) {
iptr = curname;
while((*jptr != ' ') && (*jptr != ')') && *jptr)
*iptr++ = *jptr++;
*iptr = '\0';
#ifdef DEBUG
fprintf(stderr,"\ndospecial: S_INCLUDE curname = %s\n", curname);
#endif /* DEBUG */
if((genfile = fopen(curname,"r")) == NULL) {
fprintf(stderr,"Cannot open the \\special{include()} file %s for input.\n", curname);
exit(-1);
}
/* Make the cursor position current and push it */
/*
fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
fputs(PCL4_PUSH, bitfile);
*/
while((ic = getc(genfile)) != EOF)
putc(ic, bitfile);
fclose(genfile);
/*
fputs(PCL4_POP, bitfile);
*/
}
break;
case S_MOVE: /* move(h=..dim v=..dim) */
if(!prescan) {
hoffset = voffset = 0L;
relative = TRUE;
while(*jptr != ')'){
while(*jptr == ' ')
jptr++;
if(!(c = *jptr++));
if(*jptr == '=') jptr++;
switch(c)
{
case 'h':
hoffset = dim_to_dots(jptr, resolution);
break;
case 'v':
voffset = dim_to_dots(jptr, resolution);
break;
case 'a':
relative = FALSE;
break;
case 'r':
relative = TRUE;
break;
default:
fprintf(stderr,"\ndospecial: Invalid parameter in \\special{move}\n");
break;
}
while((*jptr != ' ') && (*jptr != ')') && *jptr)
jptr++;
}
#ifdef DEBUG
fprintf(stderr,"\ndospecial: S_MOVE relative = %d, hoffset = %ld, voffset = %ld\n", relative, hoffset, voffset);
#endif /* DEBUG */
if(relative) {
if(hoffset)
fprintf(bitfile, PCL4_MOVE_HREL, hoffset);
if(voffset)
fprintf(bitfile, PCL4_MOVE_VREL, voffset);
}
else {
if(hoffset)
fprintf(bitfile, PCL4_MOVE_H_POSITION, hoffset);
if(voffset)
fprintf(bitfile, PCL4_MOVE_V_POSITION, voffset);
}
}
break;
case S_GRAFIX: /* grafix(filename [resolution]) */
if(!prescan) {
iptr = curname;
while((*jptr != ' ') && (*jptr != ')') && *jptr)
*iptr++ = *jptr++;
*iptr = '\0';
if((genfile = fopen(curname,"r")) == NULL) {
fprintf(stderr,"Cannot open the \\special{grafix()} input file %s for input.\n", curname);
exit(-1);
}
while(*jptr == ' ') jptr++;
delimptr = jptr;
while((*jptr != ' ') && (*jptr != ')') && *jptr)
jptr++;
if(jptr != delimptr)
{
*jptr = '\0';
l = 0;
while(l < GRAFLIST)
if(!strcmp(delimptr, graflist[l]))
break;
else l++;
}
else l = 2;
if(l == GRAFLIST)
{
fprintf(stderr,"\ndospecial: Invalid resolution in \\special{grafix}: %s.\n", delimptr);
l = 2;
}
if(l)
fprintf(bitfile, PCL4_GRAPHRES, graflist[l]);
/* Make the cursor position current and push it */
fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
fputs(PCL4_PUSH, bitfile);
fputs(PCL4_START_RASTER, bitfile);
pxl_rows = (getc(genfile) << 8);
pxl_rows = pxl_rows + getc(genfile);
gflag = getc(genfile);
if(!gflag)
sprintf(drawrow, PCL4_DRAWROW, row_bytes = getc(genfile));
for(i = 0 ; i < pxl_rows ; i++) {
if(gflag)
fprintf(bitfile, PCL4_DRAWROW, row_bytes = getc(genfile));
else
fputs(drawrow, bitfile);
for(j = 0 ; j < row_bytes ; j++)
putc(getc(genfile), bitfile);
}
fclose(genfile);
fputs(PCL4_END_RASTER, bitfile);
if(l)
fprintf(bitfile, PCL4_GRAPHRES, graflist[0]);
fputs(PCL4_POP, bitfile);
}
break;
case S_ORIENTATION: /* PCL5 print orientation/direction */
if(!prescan) {
if(pcllevel < 5)
fprintf(stderr,"\ndospecial: Changing print direction via \\special not supported at PCL level %d.\n Only at PCL level 5 (option -5).", pcllevel);
else {
angle = (short)atoi(jptr);
if(angle==1)
angle=90;
else if(angle==2)
angle=180;
else if(angle==3)
angle=270;
#ifdef DEBUG
fprintf(stderr,"\ndospecial: S_ORIENTATION angle = %d\n", angle);
#endif /* DEBUG */
/* Make the cursor position current */
/*
fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
*/
fprintf(bitfile, PCL5_PRINT_DIRECTION, angle);
}
}
break;
case S_FILE: /* Input file */
if(!prescan) {
iptr = curname;
while((*jptr != ' ') && *jptr)
*iptr++ = *jptr++;
*iptr = '\0';
if((genfile = fopen(curname,"r")) == NULL) {
fprintf(stderr,"Cannot open the \\special{input=} file %s for input.\n", curname);
exit(-1);
}
/* Make the cursor position current and push it */
fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
fputs(PCL4_PUSH, bitfile);
while((ic = getc(genfile)) != EOF)
putc(ic, bitfile);
fclose(genfile);
fputs(PCL4_POP, bitfile);
}
break;
case S_PCL: /* PCL code */
case S_PS: /* PostScript code */
if(!prescan) {
/* Make the cursor position current and push it */
fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
fputs(PCL4_PUSH, bitfile);
while(*jptr)
putc(*jptr++, bitfile);
fputs(PCL4_POP, bitfile);
}
break;
case S_HPGL: /* PCL5 HP-GL/2 code */
if(!prescan) {
if(pcllevel < 5)
fprintf(stderr,"\ndospecial: Using HP-GL/2 commands in \\special not supported at PCL level %d.\n Only at PCL level 5 or higher (option -5).", pcllevel);
else {
/* Make the cursor position current and push it */
fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
fputs(PCL4_PUSH, bitfile);
/* Enter HP-GL/2 mode. Pen to previous PCL pen position */
fputs(PCL5_HPGLMODE_PCLPEN, bitfile);
while(*jptr)
putc(*jptr++, bitfile);
/* Enter PCL mode. Pen to previous PCL pen position */
fputs(PCL5_PCLMODE_PCLPEN, bitfile);
fputs(PCL4_POP, bitfile);
}
}
break;
case S_RASTERFILE: /* rasterfile ...*/
if(!prescan) {
iptr = curname;
while((*jptr != ' ') && *jptr)
*iptr++ = *jptr++;
*iptr = '\0';
#ifdef DEBUG
fprintf(stderr,"\ndospecial: S_RASTERFILE curname = %s\n", curname);
#endif /* DEBUG */
if((genfile = fopen(curname,"r")) == NULL){
fprintf(stderr,"Cannot open the \\special{rasterfile} file %s for input.\n", curname);
exit(-1);
}
/* Make the cursor position current and push it */
fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
fputs(PCL4_PUSH, bitfile);
while((ic = getc(genfile)) != EOF)
putc(ic, bitfile);
fclose(genfile);
fputs(PCL4_POP, bitfile);
}
break;
case S_PJXL:
if(!prescan) {
#ifdef DEBUG
fprintf(stderr,"\ndospecial: S_PJXL jptr = %s\n", jptr);
#endif /* DEBUG */
l = 0;
while(l < GRAFLIST) {
if(!strcmp(jptr, colorlist[l]))
break;
else
l++;
}
if(l == GRAFLIST) {
fprintf(stderr,"\ndospecial: Invalid color in \\special{pjxl:}: %s.\n", jptr);
l = 0;
}
fprintf(bitfile, PJXL_TEXT_COLOR, l);
}
break;
case S_ESCAPESEQ:
case S_RAWSTRING:
case S_EM:
if(prescan) {
fprintf(stderr,"\ndospecial: \\special command not implemented: %s\n",
nextnamesfree);
}
break;
}
}
}
}